//
//  RefreshTokenService.swift
//  hello
//
//  Created by yafei li on 2025/9/19.
//

import Vapor
import Redis
import Crypto

struct RefreshTokenService {
    
    private let tokenLifespan: TimeInterval = 60 * 60 * 24 * 7 // 7天
    
    private func redisKey(for tokenHash: String) -> RedisKey {
        return RedisKey(tokenHash)
        }
    
    func generateToken() -> (token: String, hash: String) {
        let raw = [UUID().uuidString, Date().ISO8601Format()].joined(separator: "-").base64String()
        let hash = SHA256.hash(data: Data(raw.utf8)).compactMap { String(format: "%02x", $0) }.joined().base64String()
        print("生成刷新令牌: \(raw) -> \(hash)")
        return (raw,hash)
    }

    func save(tokenHash: String, userId: UUID, on req: Request) async throws {
       let key = redisKey(for: tokenHash)
        try await req.redis.setex(key, toJSON: userId.uuidString, expirationInSeconds: Int(tokenLifespan))
   }

   func consume(tokenHash: String, on req: Request) async throws -> UUID? {
       let key = redisKey(for: tokenHash)
       let userIDString = try await req.redis.get(key, as: String.self).get()
       guard let userId = userIDString?.getRedisValue() else { return nil }
       _ =  try await req.redis.delete([key]).get() // 原子异步删除，防重放
       let uid = UUID(uuidString: userId)
       return uid
   }
    
    /// 主动撤销 Token（可选）
    func revoke(tokenHash: String, on req: Request) async throws {
        let key = redisKey(for: tokenHash)
        _ = try await req.redis.delete([key]).get()
    }

    /// 检查 Token 是否存在（调试用）
    func exists(tokenHash: String, on req: Request) async throws -> Bool {
        let key = redisKey(for: tokenHash)
        return try await req.redis.exists(key) > 0
    }
}
